package cn.yunyichina.provider.cashpool.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

import cn.yunyichina.provider.cashpool.dao.CouponCodeDao;
import cn.yunyichina.provider.cashpool.dao.CouponDao;
import cn.yunyichina.provider.cashpool.dao.CouponPushDao;
import cn.yunyichina.provider.cashpool.entity.Coupon;
import cn.yunyichina.provider.cashpool.entity.CouponCode;
import cn.yunyichina.provider.cashpool.entity.CouponPush;
import cn.yunyichina.provider.cashpool.vo.CouponPushVo;
import cn.yunyichina.provider.cashpool.vo.CouponVo;
import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.framework.page.PageInfo;
import cn.yunyichina.provider.framework.utils.UUIDUtil;
import cn.yunyichina.provider.iface.entity.alipay.AddCouponRequest;
import cn.yunyichina.provider.iface.entity.alipay.AddCouponResponse;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;

@Service
public class CouponServiceImpl {
    private Logger logger = LoggerFactory.getLogger(CouponServiceImpl.class);

    @Autowired
    private CouponDao couponDao;

    @Autowired
    private CouponCodeDao couponCodeDao;

    @Autowired
    private CouponPushDao couponPushDao;

    /**
     * 添加优惠券 - yyt.cashpool.coupon.add
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response addCoupon(String json, String sessionId) {
        logger.info("addCoupon start json=" + json);
        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            Coupon record = new Coupon();
            BeanUtils.copyProperties(couponVo, record);

            record.setId(UUIDUtil.get32UUID());
            record.setCreateTime(DateUtils.dateToString(new Date()));
            couponDao.insert(record);
        } catch (Exception e) {
            logger.error("addCoupon error", e);
            return Response.failure();
        }
        return Response.success();
    }

    /**
     * 获取所有所属公司 - yyt.cashpool.coupon.org.get
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response getCouponOrg(String json, String sessionId) {
        logger.info("getCouponOrg start json=" + json);
        Response response = new Response();
        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            List<String> selects = new ArrayList<String>();
            selects.add("distinct coupon_org_name");
            selects.add("coupon_org_id");

            List<String> orderColumns = new ArrayList<String>();
            orderColumns.add("create_time");

            Map<String, Object> map = new HashMap<String, Object>();

            PageInfo pageInfo = new PageInfo();
            pageInfo.setPageNum(couponVo.getPageNum());
            pageInfo.setPageSize(couponVo.getPageSize());

            Coupon wheres = new Coupon();
            if (StringUtils.isNotBlank(couponVo.getCouponOrgName())) {
                wheres.setCouponOrgName(couponVo.getCouponOrgName());
            }
            List<Coupon> coupons = couponDao.select(wheres, selects, orderColumns, false, pageInfo);
            map.put("coupons", coupons);

            long couponsCount = couponDao.selectCount(wheres);
            map.put("count", couponsCount);

            response.setResult(JsonUtils.toJsonString(map));
        } catch (Exception e) {
            logger.error("getCouponOrg error", e);
            return Response.failure();
        }

        logger.info("getCouponOrg response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 获取优惠券列表 - yyt.cashpool.coupon.list
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response listCoupon(String json, String sessionId) {
        logger.info("listCoupon start json=" + json);
        Response response = new Response();
        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            List<String> orderColumns = new ArrayList<String>();
            orderColumns.add("create_time");

            PageInfo pageInfo = new PageInfo();
            pageInfo.setPageNum(couponVo.getPageNum());
            pageInfo.setPageSize(couponVo.getPageSize());

            Map<String, Object> map = new HashMap<String, Object>();

            Coupon wheres = new Coupon();
            if (StringUtils.isNotBlank(couponVo.getPushType())) {
                wheres.setCreateTime(DateUtils.getDateStr(new Date()));
                // 0-停止发放   1-正在发放  2-未开始发放
                wheres.setPushType(couponVo.getPushType());
            }
            if (StringUtils.isNotBlank(couponVo.getCouponStartTime())) {
                wheres.setCouponStartTime(couponVo.getCouponStartTime());
            }
            if (StringUtils.isNotBlank(couponVo.getCouponEndTime())) {
                wheres.setCouponEndTime(couponVo.getCouponEndTime());
            }

            // 借用couponCount存放时间过滤情况
            if (StringUtils.isNotBlank(couponVo.getCouponStartTime())
                    && StringUtils.isNotBlank(couponVo.getCouponEndTime())) {
                wheres.setCouponCount(1);
            } else if (StringUtils.isNotBlank(couponVo.getCouponStartTime())) {
                wheres.setCouponCount(2);
            } else if (StringUtils.isNotBlank(couponVo.getCouponEndTime())) {
                wheres.setCouponCount(3);
            }

            if (StringUtils.isNotBlank(couponVo.getCouponName())) {
                wheres.setCouponName(couponVo.getCouponName());
            }
            
            if (StringUtils.isNotBlank(couponVo.getCouponOrgId())) {
                wheres.setCouponOrgId(couponVo.getCouponOrgId());
            }
            
            List<Coupon> coupons = couponDao.selectByCondition(wheres, null, orderColumns, false, pageInfo);
            map.put("coupons", coupons);

            long couponsCount = couponDao.selectByConditionCount(wheres);
            map.put("count", couponsCount);

            response.setResult(JsonUtils.toJsonString(map));
        } catch (Exception e) {
            logger.error("listCoupon error", e);
            return Response.failure();
        }

        logger.info("listCoupon response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 获取优惠券信息 - yyt.cashpool.coupon.get
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response getCoupon(String json, String sessionId) {
        logger.info("getCoupon start json=" + json);
        Response response = new Response();

        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            Coupon coupon = couponDao.selectById(couponVo.getId());
            response.setResult(JsonUtils.toJsonString(coupon));
        } catch (Exception e) {
            logger.error("getCoupon error", e);
            return Response.failure();
        }

        logger.info("getCoupon response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 修改优惠券信息 - yyt.cashpool.coupon.update
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response updateCoupon(String json, String sessionId) {
        logger.info("updateCoupon start json=" + json);
        Response response = new Response();

        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            Coupon record = new Coupon();
            BeanUtils.copyProperties(couponVo, record);
            logger.info("updateCoupon update request=" + JSON.toJSONString(record));
            couponDao.update(record);
        } catch (Exception e) {
            logger.error("updateCoupon error", e);
            return Response.failure();
        }

        logger.info("updateCoupon response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 删除优惠券信息 - yyt.cashpool.coupon.delete
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response deleteCoupon(String json, String sessionId) {
        logger.info("deleteCoupon start json=" + json);
        Response response = new Response();

        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            String ids = couponVo.getId();
            List<String> list = new ArrayList<String>();
            if (ids.contains(",")) {
                String[] idsArray = ids.split(",");
                list = Arrays.asList(idsArray);
            } else {
                list.add(ids);
            }
            logger.info("deleteCoupon delete request=" + JSON.toJSONString(list));
            couponDao.deleteByIds(list);
        } catch (Exception e) {
            logger.error("deleteCoupon error", e);
            return Response.failure();
        }

        logger.info("updateCoupon response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 获取可领取优惠券 - yyt.cashpool.coupon.after.payment.get
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response getCouponAfterPayment(String json, String sessionId) {
        logger.info("getCouponAfterPayment start json=" + json);
        Response response = new Response();

        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);
            CouponPushVo couponPushVo = JsonUtils.parseObject(json, CouponPushVo.class);

            Map<String, Object> params = new HashMap<String, Object>();
            Calendar calendar = Calendar.getInstance();
            params.put("nowTime", DateUtils.dateToString(calendar.getTime()));
            calendar.add(Calendar.MINUTE, Coupon.COUPON_RECEIVE_TIMEOUT);
            params.put("pushTime", DateUtils.dateToString(calendar.getTime()));
            params.put("nowTime", DateUtils.dateToString(new Date()));
            params.put("patSex", couponPushVo.getPatSex().intValue());
            params.put("openId", couponPushVo.getOpenId());
            params.put("patAge", couponPushVo.getPatAge().intValue());
            if (StringUtils.isNotBlank(couponVo.getPushType())) {
                params.put("pushType", couponVo.getPushType());
            }
            if (StringUtils.isNotBlank(couponVo.getPushKeywords())) {
                params.put("keyword", couponVo.getPushKeywords());
            }
            List<Map<String, Object>> datamap = couponDao.selectCouponAfterPayment(params);
            logger.info("getCouponAfterPayment response datamap=" + JSON.toJSONString(datamap));
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("coupons", datamap);

            long couponsCount = couponDao.selectCouponAfterPaymentCount(params);
            map.put("count", couponsCount);

            // 把已推送already_pushed_count字段值加1
            for (Map<String, Object> data : datamap) {
                String couponId = (String) data.get("coupon_id");
                String codeId = (String) data.get("code_id");
                String code = (String) data.get("coupon_code");

                // 更新优惠券已推送数
                Coupon coupon = couponDao.selectById(couponId);
                coupon.setAlreadyPushedCount(coupon.getAlreadyPushedCount().intValue() + 1);
                couponDao.update(coupon);

                // 更新券码为已推送、推送时间
                String nowTime = DateUtils.dateToString(new Date());
                CouponCode couponCode = couponCodeDao.selectById(codeId);
                couponCode.setIsPushed(1);
                couponCode.setPushTime(nowTime);
                couponCode.setOpenId(couponPushVo.getOpenId());
                couponCodeDao.update(couponCode);

                // 优惠券推送表增加一条信息
                CouponPush couponPush = new CouponPush();
                couponPush.setId(UUIDUtil.get32UUID());
                couponPush.setOrderNo(couponPushVo.getOrderNo());
                couponPush.setOrderType(couponPushVo.getOrderType());
                couponPush.setOpenId(couponPushVo.getOpenId());
                couponPush.setCouponId(couponId);
                couponPush.setCouponCode(code);
                couponPush.setPatName(couponPushVo.getPatName());
                couponPush.setPatMobile(couponPushVo.getPatMobile());
                couponPush.setPatArea(couponPushVo.getPatArea());
                couponPush.setPatSex(couponPushVo.getPatSex());
                couponPush.setPushTime(nowTime);
                couponPush.setCreateTime(nowTime);
                couponPushDao.insert(couponPush);
            }

            response.setResult(JsonUtils.toJsonString(map));
        } catch (Exception e) {
            logger.error("getCouponAfterPayment error", e);
            return Response.failure();
        }

        logger.info("getCouponAfterPayment response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 领取优惠券 - yyt.cashpool.coupon.receive
     * 
     * @param json
     * @param sessionId
     * @return
     */
    public Response receiveCoupon(String json, String sessionId) {
        logger.info("receiveCoupon start json=" + json);
        Response response = new Response();

        try {
            CouponVo couponVo = JsonUtils.parseObject(json, CouponVo.class);

            AddCouponRequest acr = new AddCouponRequest();
            acr.setAppType("ALIPAY");
            acr.setAppId(couponVo.getAppId());
            acr.setTemplateId(couponVo.getTemplateId());
            acr.setOrderNo(couponVo.getOrderNo());
            acr.setCouponCode(couponVo.getCouponCode());
            logger.info("receiveCoupon, addCouponInstance request=" + JSON.toJSONString(acr));
            // 调用支付模块添加优惠券接口
            AddCouponResponse couponResponse = PayService.getPayClient().addCouponInstance(acr);
            if (couponResponse != null) {
                logger.info("receiveCoupon, addCouponInstance couponResponse=" + JSON.toJSONString(couponResponse));
                Coupon coupon = couponDao.selectById(couponVo.getId());
                logger.info("receiveCoupon coupon=" + JSON.toJSONString(coupon));
                // 更新优惠券已领取数
                coupon.setAlreadyReceivedCount(coupon.getAlreadyReceivedCount().intValue() + 1);
                couponDao.update(coupon);

                // 更新券码为已领取、领取时间
                CouponCode couponCode = couponCodeDao.selectById(couponVo.getCodeId());
                couponCode.setIsReceived(1);
                couponCode.setReceiveTime(DateUtils.dateToString(new Date()));
                couponCode.setOpenId(couponVo.getOpenId());
                couponCodeDao.update(couponCode);
                
                CouponPush wheres = new CouponPush();
                wheres.setOrderNo(couponVo.getOrderNo());
                wheres.setOpenId(couponVo.getOpenId());
                wheres.setCouponCode(couponVo.getCouponCode());
                List<CouponPush> couponPushs = couponPushDao.select(wheres);
                CouponPush couponPush = couponPushs.get(0);
                couponPush.setIsReceived(1);
                couponPushDao.update(couponPush);
            } else {
                return Response.failure();
            }
        } catch (Exception e) {
            logger.error("receiveCoupon error", e);
            return Response.failure();
        }

        logger.info("receiveCoupon response=" + JSON.toJSONString(response));
        return response;
    }
}
